`timescale 1ns / 1ps
`default_nettype none
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 2019/07/03 15:52:50
// Design Name: 
// Module Name: MemState
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////

//注意，这一个模块里面实际上把WriteBack级给包括进来�//在后续扩展中，很可能会在这个模块中加入内部流水级,也就是说，很可能这个模块是二级流�
module MemState(
        input   wire    Clk,
        input   wire    Clr,
		input	wire    [31:0]	E_PC,
        input   wire    [31:0]  E_Instr,
        input   wire    [31:0]  E_MemWriteData,
        input   wire    [4:0]   E_RtID,
        input   wire    [31:0]  E_Data,
        input   wire    E_WriteRegEnable,
        input   wire    [4:0]   E_RegId,
        input   wire    [31:0]  E_Mem_read_data,
        input	wire    E_MemReadEnable,
        input	wire    [4:0]   E_ExtType,
        output  wire    [31:0]  E_MemWriteData_MFed,
        output  reg		        M_WriteRegEnable,
        output  reg     [4:0]   M_RegId,
        output  wire    [31:0]  M_Data,
		output  reg     [31:0]	M_PC
    );
    ///////////////////转发//////////////////////////////
    wire    [31:0]  MF_Rt = (M_WriteRegEnable && M_RegId==E_RtID)				?   M_Data:
																					E_MemWriteData;
    assign  E_MemWriteData_MFed = MF_Rt;
    wire [31:0] MemReadData_Inter = E_Mem_read_data;
    ////////////////////////////
    wire [31:0] Data_to_next_state = E_MemReadEnable ? MemReadData_Inter:E_Data;
    wire [1:0]  Offset_Inter = E_Data[1:0];


    reg [1:0] M_Offset;
    reg [4:0] M_ExtType;
    reg [31:0] M_RawData;
	reg		M_MemReadEnable;
	initial begin
		M_WriteRegEnable <= 0;
		M_RegId <= 0;
		M_Offset <= 0;
		M_ExtType <= 0;
		M_RawData <= 0;
		M_MemReadEnable <= 0;
		M_PC <= 0;
	end
    always @ (posedge Clk) begin
		if(Clr) begin
			M_WriteRegEnable <= 0;
			M_RegId <= 0;
			M_Offset <= 0;
			M_ExtType <= 0;
			M_RawData <= 0;
			M_MemReadEnable <= 0;
			M_PC <= 0;
		end
		else begin
			M_WriteRegEnable <= E_WriteRegEnable;
			M_RegId <= E_RegId;
			M_Offset <= Offset_Inter;
			M_ExtType <= E_ExtType;
			M_RawData <= Data_to_next_state;
			M_MemReadEnable <= E_MemReadEnable;
			M_PC <= E_PC;
		end
    end
    //////////////////////////////////////

	wire [31:0] ExtMemData;
    MemExtUnit MemExtUnit(  .RawMemData(M_RawData),
                            .Offset(M_Offset),
                            .ExtType(M_ExtType),
                            .ExtMemData(ExtMemData));
    assign M_Data = M_MemReadEnable ? ExtMemData:M_RawData;
endmodule
